package com.example.selfservicestation.util

import com.example.selfservicestation.R
import com.example.selfservicestation.event.AudioEvent
import com.example.selfservicestation.event.ToastEvent
import org.greenrobot.eventbus.EventBus
import java.io.File

object Tip {

    /**
     * Toast 提示
     */
    fun toast(msg: String, log: Boolean = true) {
        EventBus.getDefault().post(ToastEvent(msg))
        if (log) {
            Logger.i("TIP", msg)
        }
    }

    /**
     * 播放音频
     */
    fun audio(resId: Int, delayMillis: Long = 0, callback: (() -> Unit)? = null) {
        synchronized(this) {
            if (delayMillis <= 0) {
                EventBus.getDefault().post(AudioEvent(resId = resId, callback = callback))
            } else {
                Executor.delayOnIO({
                    EventBus.getDefault().post(AudioEvent(resId = resId, callback = callback))
                }, delayMillis)
            }
        }
    }

    /**
     * 播放音频
     */
    fun audio(file: File, callback: (() -> Unit)? = null) {
        synchronized(this) {
            EventBus.getDefault().post(AudioEvent(file = file, callback = callback))
        }
    }

    /**
     * 播放整数声音
     * @param num 0 - 9 范围内的整数
     */
    fun audioNum(num: Int) {
        synchronized(this) {
            when (num) {
                9 -> {
                    audio(R.raw.n9)         // 播放 9
                }

                8 -> {
                    audio(R.raw.n8)         // 播放 8
                }

                7 -> {
                    audio(R.raw.n7)         // 播放 7
                }

                6 -> {
                    audio(R.raw.n6)         // 播放 6
                }

                5 -> {
                    audio(R.raw.n5)         // 播放 5
                }

                4 -> {
                    audio(R.raw.n4)         // 播放 4
                }

                3 -> {
                    audio(R.raw.n3)         // 播放 3
                }

                2 -> {
                    audio(R.raw.n2)         // 播放 2
                }

                1 -> {
                    audio(R.raw.n1)         // 播放 1
                }

                0 -> {
                    audio(R.raw.n0)         // 播放 0
                }
            }
        }
    }

    /**
     * 播放数字声音算法（可以包含小数）
     * @param decimal 待播放的十进制数字
     */
    fun speakNum(decimal: String, endResId: Int? = null, onComplete: (() -> Unit)? = null) {
        synchronized(this) {
            val queue = ArrayList<Int>()
            val digits = decimal.split(".")
            when (digits.size) {
                1 -> {
                    queueNum(queue, digits[0].toInt())
                }

                2 -> {
                    queueNum(queue, digits[0].toInt())
                    queue.add(R.raw.ndot)
                    digits[1].forEach {
                        queueNum(queue, it.code - 48)
                    }
                }

                else -> {
                    toast("无法播放非数字：${decimal}")
                }
            }
            endResId?.let { queue.add(it) }
            speakNum(queue, 0, onComplete)
        }
    }

    @Suppress("unused")
    fun speakNum(num: Int, endResId: Int? = null, onComplete: (() -> Unit)? = null) {
        synchronized(this) {
            val queue = ArrayList<Int>()
            queueNum(queue, num)
            endResId?.let { queue.add(it) }
            speakNum(queue, 0, onComplete)
        }
    }


    private fun speakNum(queue: ArrayList<Int>, index: Int, onComplete: (() -> Unit)? = null) {
        if (index >= queue.size) {
            return
        }
        Logger.d("speakNum", "" + index)
        Executor.runOnIO {
            Audio.effectByResId(queue[index])
            val next = index + 1
            if (next < queue.size) {
                Executor.delayOnIO({
                    speakNum(queue, next, onComplete)
                }, 500)
            } else if (next == queue.size) {
                onComplete?.invoke()
            }
        }
    }


    /**
     * 播放整数声音算法
     * @param num 待播放的整数
     */
    private fun queueNum(queue: ArrayList<Int>, num: Int) {
        if (num >= 10000) {
            queueNum(queue, num, 10000, R.raw.n10000)      // 播放 万 级数字
        } else if (num >= 1000) {
            queueNum(queue, num, 1000, R.raw.n1000)        // 播放 千 级数字
        } else if (num >= 100) {
            queueNum(queue, num, 100, R.raw.n100)          // 播放 百 级数字
        } else if (num >= 10) {
            queueNum(queue, num, 10, R.raw.n10)            // 播放 十 级数字
        } else if (num == 9) {
            queue.add(R.raw.n9)         // 播放 9
        } else if (num == 8) {
            queue.add(R.raw.n8)         // 播放 8
        } else if (num == 7) {
            queue.add(R.raw.n7)         // 播放 7
        } else if (num == 6) {
            queue.add(R.raw.n6)         // 播放 6
        } else if (num == 5) {
            queue.add(R.raw.n5)         // 播放 5
        } else if (num == 4) {
            queue.add(R.raw.n4)         // 播放 4
        } else if (num == 3) {
            queue.add(R.raw.n3)         // 播放 3
        } else if (num == 2) {
            queue.add(R.raw.n2)         // 播放 2
        } else if (num == 1) {
            queue.add(R.raw.n1)         // 播放 1
        } else if (num == 0) {
            queue.add(R.raw.n0)         // 播放 0
        }
    }

    private fun queueNum(queue: ArrayList<Int>, num: Int, radix: Int, resId: Int) {
        queueNum(queue, num / radix)  // 播放倍数
        queue.add(resId)                // 播放倍数单位（十、百、千、万）
        val mod = num % radix
        if (mod > 0) {
            if (mod < radix / 10) {
                queue.add(R.raw.n0)     // 播放 0
            }
            queueNum(queue, mod)           // 播放余数
        }
    }

}